/*
 * This file is Copyright 2002-2006 Loyola University Chicago,
 * Department of Computer Science and the Emerging Technologies Laboratory.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License via
 *    http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.citep.web.gwt.widgets;

import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Timer;

import com.google.gwt.user.client.Event;

import java.util.ArrayList;

public class ShortcutTable extends Grid {
	
	protected static int MAX_ROWS = 10;

	protected ArrayList shortcuts;
	protected int rowLimit;

	protected Hyperlink moreLink;
	
	
	public ShortcutTable(String title) {
		super(1,1);
		
		shortcuts = new ArrayList();
		setStyleName("shortcuts");
		setText(0,0,title);
		getCellFormatter().setStyleName(0, 0, "shortcuts_header");
		setCellSpacing(0);
		sinkEvents(Event.ONMOUSEOVER);
		sinkEvents(Event.ONMOUSEOUT);
		rowLimit = MAX_ROWS;
	}

	public ShortcutTable(String title, int rowLimit) {
		this(title);
		
		if(rowLimit < 1)
			throw new RuntimeException("Shortcut table: rowLimit cannot be less than 1");

		this.rowLimit = rowLimit;
		
		//+2 for header and more link
		resize(rowLimit+2,1);
	}

	public void setMoreLink(Hyperlink link) {
		this.moreLink = link;
	}

	
    private Element getMouseEventTargetCell(Event event) {
        Element td = DOM.eventGetTarget(event);
        //locate enclosing td element
        while (!DOM.getAttribute(td, "tagName").equalsIgnoreCase("td")) {
            // If we run out of elements, or run into the table itself, then give up.
            if ((td == null) || DOM.compare(td, getElement()))
                return null;
            td = DOM.getParent(td);
        }
        //test if the td is actually from this table
        Element tr = DOM.getParent(td);
        Element body = DOM.getParent(tr);
        if (DOM.compare(body, this.getBodyElement())) {
            return td;
        }
        //Didn't find appropriate cell
        return null;         
    }

    //gets the row index of a given table cell
    protected int getRowIndex(Element cell) {
		Element row = DOM.getParent(cell);
		Element table = DOM.getParent(row);

		return DOM.getChildIndex(table, row);
    }
    
    protected void onMouseEnterRow(int idx) {
    	//only hightlight rows with shortcuts and the more link
    	if(idx <= shortcuts.size() || idx == (rowLimit+1))
    		this.getRowFormatter().setStyleName(idx, "shortcut_row_highlighted");
    }
    
    protected void onMouseLeaveRow(int idx) {
    	//only hightlight rows with shortcuts and the more link
    	if(idx <= shortcuts.size() || idx == (rowLimit+1))
    		this.getRowFormatter().setStyleName(idx, "shortcut_row_normal");
    }
    
	public void onBrowserEvent(Event e) {
		Element cell;
		switch(DOM.eventGetType(e)) {
			case Event.ONMOUSEOVER:
				cell = getMouseEventTargetCell(e);
				
				
				if(cell == null) return;

				DOM.setStyleAttribute(cell, "backgroundColor", "");
				
				onMouseEnterRow(getRowIndex(cell));
				
				break;
			case Event.ONMOUSEOUT:

				cell = getMouseEventTargetCell(e);

				if(cell == null) return;
				
				onMouseLeaveRow(getRowIndex(cell));
				
				break;
		}
		
	}

	protected int getShortCutRowCount() {
		int shortCutRows = shortcuts.size();

		if(shortCutRows >= rowLimit)
			shortCutRows = rowLimit;

		return shortCutRows;
	}
	
	public void updateShortcut(final Shortcut shortcut, final boolean highlight) {

		int shortCutRows = this.getShortCutRowCount();
		
		for(int i = 0; i < shortcuts.size(); i++) {
			Shortcut currShortcut = (Shortcut)shortcuts.get(i);
			
			if(currShortcut.equals(shortcut)) {
				shortcuts.set(i,shortcut);
			}
		}

		java.util.Collections.sort(shortcuts);
		
		//set the text of each cell to reflect the new order
		for(int i = 0; i < shortCutRows; i++) {
			final Shortcut currShortCut = (Shortcut)shortcuts.get(i);
			
			Hyperlink link = new Hyperlink(currShortCut.getName(),currShortCut.getHistoryToken());
/*			link.addClickListener(new ClickListener() {
				public void onClick(Widget w) {
					currShortCut.execute();
				}
			});*/
			
			//setText(i+1,0,currShortCut.getName());
			setWidget(i+1,0,link);
		}
		
		if(highlight)
			highLightShortCut(shortcut);
	}
	
	public void addShortcut(final Shortcut shortcut, final boolean highlight) {
		//add the shortcut to our list of shortcuts
		shortcuts.add(shortcut);

		int shortCutRows = this.getShortCutRowCount();
		
		//sort it by name
		java.util.Collections.sort(shortcuts);
		
		//set the text of each cell to reflect the new order
		for(int i = 0; i < shortCutRows; i++) {
			final Shortcut currShortCut = (Shortcut)shortcuts.get(i);
			
			Hyperlink link = new Hyperlink(currShortCut.getName(),currShortCut.getHistoryToken());
/*			link.addClickListener(new ClickListener() {
				public void onClick(Widget w) {
					currShortCut.execute();
				}
			});*/
			
			setWidget(i+1,0,link);
		}
		/*
		 * If we have just exceeded the row limit, add a new
		 */

		//for now add the shortcuts link when there is at least one entry
//		if(shortcuts.size() == (rowLimit+1) && moreLink != null) {
		if(moreLink != null) {
			if(shortcuts.size() == 1) {
			
				//+2 because of header and 'more' link
				setWidget(rowLimit+1,0,moreLink);
				getCellFormatter().addStyleName(rowLimit+1, 0, "shortcut_more_link");
			
			}
		}
			
		if(highlight)
			highLightShortCut(shortcut);
	}
	
	public void highLightShortCut(final Shortcut shortcut) {
		
		//search the grid to see if the shortcut is visible
		int dataRows = getShortCutRowCount();
		
		for(int i = 0; i < dataRows; i++) {
			Shortcut currShortCut = (Shortcut)shortcuts.get(i);
			
			//if it is, highlight it
			if(currShortCut.equals(shortcut))
				highlightRow(getCellFormatter().getElement(i+1,0));
		}
		
	}
	
	public void clearEntries() {
		int dataRows = getShortCutRowCount();
		for(int i = 0; i < dataRows; i++) {
			this.clearCell(i+1, 0);
			this.unHighlightRow(this.getCellFormatter().getElement(i+1, 0));
		}
		
		this.unHighlightRow(this.getCellFormatter().getElement(rowLimit+1,0));
		
		shortcuts.clear();
	}
	
	protected void highlightRow(final Element e) {
		DOM.setStyleAttribute(e, "backgroundColor", "#d0dffe");
		
		
		Timer t = new Timer() {
			public void run() {
				FaderQueue q = new FaderQueue(40,40);
				q.addElement(e, "backgroundColor", "#d0dffe", "#bbd1fe");
				q.start();
			}
		};
		
		t.schedule(500);
	}
	
	protected void unHighlightRow(final Element e) {
		DOM.setStyleAttribute(e, "backgroundColor", "#bbd1fe");
	}
}
